#!/bin/bash
input=$1
type=0
pid=
ServiceName=
checkState=0

now() {
  date "+%Y-%m-%d %H:%M:%S"
}

#根据服务名查询进程PID
queryPidByServiceName() {
  count=$(ps -ef | grep -v 'grep' | grep -v "$0" | grep 'java' | grep -c "$ServiceName")
  if [ "$count" -ne 1 ]; then
    echo "$(now) ERROR--->Has no or multi processes with the name of '$ServiceName'. Count = $count"
    pid=
  else
    pid=$(ps -ef | grep -v 'grep' | grep -v "$0" | grep 'java' | grep "$ServiceName" | awk '{print $2}')
  fi
}

#检查PID对应的进程是否存在
checkProcessExist() {
  if [ -z "$pid" ]; then
    echo "$(now) ERROR--->Don't have a java process with the pid of '$pid'."
    checkState=1
    return
  fi
  echo "$(now) INFO--->Monitor Pid value is: $pid"
  pCount=$(jps | grep -c "$pid")
  if [ "$pCount" -ne 1 ]; then
    echo "$(now) ERROR--->Don't have a java process with the pid of '$pid'."
    checkState=1
    return
  fi
  checkState=0
}

echo ""
if [ -n "$input" ]; then
  echo "$(now) INFO--->Check input param type."
  if [ "$input" -ge 0 ] 2>/dev/null; then
    echo "$(now) INFO--->Input param type is a number."
    pid=$input
    type=1
  elif [ $type = 0 ] && [ -e "$input" ] 2>/dev/null; then
    echo "$(now) INFO--->Input param type is pid file path."
    pid=$(cat "$input")
    type=2
  elif [ $type = 0 ] 2>/dev/null; then
    ServiceName=$input
    echo "$(now) INFO--->Input param type is a service name. Service name is '$ServiceName'."
    queryPidByServiceName
    type=3
  fi
  checkProcessExist
  if [ $checkState -eq 1 ]; then
    exit 1
  fi
else
  echo "$(now) ERROR--->Missing param, the value of param may be a real Pid value、a path of Pid file or a service name."
  exit 1
fi

#cpu监控值
cpuRate=95
if [ -n "$2" ] && [ "$2" -ge 0 ]; then
  cpuRate=$2
fi

doMonitor() {
  echo "$(now) INFO--->Begin record busy threads..."
  #打印繁忙线程日志的输出文件
  busyThreadLog="/data/logs/busyThreadLog-$pid.txt"
  #执行打印繁忙线程任务的进程PID，即执行show-busy-java-threads.sh脚本的进程PID
  busyThreadPid="/data/logs/busyThreadPid"
  #每隔5秒执行一次，执行60次，打印占用cpu资源top20的线程，-p表示java进程pid，-a追加的形式插入文件
  nohup sh show-busy-java-threads.sh 5 60 -c 20 -p "$pid" >"$busyThreadLog" &
  echo $! >"${busyThreadPid}"
}

highTime=0
monitor() {
  echo "$(now) INFO--->Begin monitor..."
  while true; do
    #cpu=$(ps --no-heading --pid="$pid" -o pcpu)
    cpu=$(top -b -n 1 -p "$pid" | grep 'java' | awk '{print $9}')
    if [ -z "$cpu" ]; then
      if [ "$type" -eq 3 ]; then
        while true; do
          queryPidByServiceName
          checkProcessExist
          if [ $checkState = 0 ]; then
            break
          fi
          sleep 3
        done
      else
        checkProcessExist
        if [ $checkState = 1 ]; then
          exit 1
        fi
      fi
    else
      echo "$(now) INFO--->PId is $pid, rate of cpu is $cpu%."
      compare=$(echo "$cpu" \>"$cpuRate" | bc)
      if [ "$compare" -eq 1 ]; then
        highTime=$((highTime + 1))
        if [ "$highTime" -gt 3 ]; then
          highTime=0
          doMonitor
          sleep 300
        fi
        sleep 10
      else
        highTime=0
      fi
    fi
    sleep 3
  done
}

monitor
